﻿Imports LinqXmlData
Imports System.Windows.Forms
Imports System.Text.RegularExpressions

Public Class Form1

    Public high As Boolean = True

    Public keywords As String() = {"public", "using", "static", "class", "namespace", _
                                   "method", "field", "end", "new", "auto", "ansi", _
                                   "beforefieldinit", "assembly", "var", "as", "on", "off", _
                                   "private", "virtual", "specialname", "hidebysig", _
                                   "hasdefault", "none", "abstract", "sealed", "gettype", _
                                   "import", "extends", "if", "then", "else", "castclass", _
                                   "return", "label", "place", "goto", "null", "image", "#singularity", _
                                   "#include", "#xmldoc", "#newres", "newarr", "ver", "and", "or", "xor", _
                                   "throw", "try", "catch", "finally", "me", "property", "ptr", "#debug", _
                                   "get", "set", "enum", "literal", "initonly", "#refasm", "#makeasm", "#stdasm"}

    Public keywords2 As String() = {"void", "integer", "string", "double", _
                                    "boolean", "char", "decimal", "long", _
                                    "sbyte", "short", "single", "object", _
                                     "integer[]", "string[]", "double[]", _
                                    "boolean[]", "char[]", "decimal[]", "long[]", _
                                    "sbyte[]", "short[]", "single[]", "object[]"}

    Public doparse As Boolean = True

    Private Sub address_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles address.TextChanged
        If My.Computer.FileSystem.FileExists(address.Text) Then
            OpenToolStripMenuItem.Enabled = True
        Else
            OpenToolStripMenuItem.Enabled = False
        End If
    End Sub


    Private Sub OpenCode()
        Try
            doparse = False
            code.LoadFile(address.Text, RichTextBoxStreamType.PlainText)

            If code.Text <> "" Then
                Dim split As String() = code.Text.Split(New [Char]() {vbLf})

                code.Clear()

                Dim len As Integer = split.Length - 1
                Dim i As Integer

                For i = 0 To len
                    Dim s As String = split(i)
                    If i = len Then
                        ParseAll(s, True)
                    Else
                        ParseAll(s, False)
                    End If

                Next

            End If
            doparse = True
        Catch ex As Exception
            MsgBox(ex)
            'MsgBox("Error Loading File")
        End Try

        Dim del() As String = {"\"}
        Dim asplit() As String = StringParserArrDs(address.Text, del)
        Me.Text = "dylan.NET Editor - " & asplit(UBound(asplit))
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub

    Private Sub SaveCode()
        Dim addr As String = address.Text
        Try
            If My.Computer.FileSystem.FileExists(addr) = False Then

                Dim slashcount As Integer = 0
                Dim len As Integer = addr.Length - 1
                Dim i As Integer = -1

                Do Until i = len

                    i = i + 1
                    Dim ch As String = addr.Chars(i)
                    If ch = "\" Then
                        slashcount = i
                    End If

                Loop

                Dim d As String = ""
                i = -1

                Do Until i = slashcount
                    i = i + 1
                    d = d & addr.Chars(i)
                Loop

                If My.Computer.FileSystem.DirectoryExists(d) = True Then

                Else

                    My.Computer.FileSystem.CreateDirectory(d)

                End If

            End If

            code.SaveFile(address.Text, RichTextBoxStreamType.PlainText)

        Catch ex As Exception
            MsgBox("Error Saving File")
        End Try
    End Sub



    Sub Compile()

        SaveCode()
        Process.Start("dylan.NET_Compiler.exe", address.Text)

    End Sub


    Sub ParseAll(ByVal line As String, ByVal endingb As Boolean)
        Dim r As New Regex("([ \t{}()<>:;$,])")
        Dim tokens As String() = r.Split(line)

        Dim ending As Boolean = endingb

        Dim ins As Boolean = False
        Dim i2 As Integer
        Dim len As Integer = tokens.Length - 1

        For i2 = 0 To len

            Dim token As String = tokens(i2)

            ' Set the token's default color and font.
            code.SelectionColor = Color.Black
            code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Regular)

            ' Check for a comment.
            If token = "//" OrElse token.StartsWith("//") Then
                ' Find the start of the comment and then extract the whole comment.
                Dim index As Integer = line.IndexOf("//")
                If index = 0 Or index > 0 Then
                    Dim comment As String = line.Substring(index, line.Length - index)
                    code.SelectionColor = Color.Green
                    code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Regular)
                    code.SelectedText = comment
                End If
                Exit For
            End If

            If token Like """" & "*" Then
                If ins = True Then
                    ins = False
                Else
                    ins = True
                End If
                If token Like """" & "*" & """" Then
                    ins = False
                End If
                code.SelectionColor = Color.IndianRed
                code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
            ElseIf token Like "*" & """" Then
                code.SelectionColor = Color.IndianRed
                code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
                ins = False
            End If

            If token Like "'*" Then
                If ins = True Then
                    ins = False
                Else
                    ins = True
                End If
                If token Like "'*'" Then
                    ins = False
                End If
                code.SelectionColor = Color.IndianRed
                code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
            ElseIf token Like "*'" Then
                code.SelectionColor = Color.IndianRed
                code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
                ins = False
            End If

            If ins = True Then
                code.SelectionColor = Color.IndianRed
                code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
            End If

            If ins = False Then
                ' Check whether the token is a keyword. 
                For i As Integer = 0 To keywords.Length - 1
                    If keywords(i) = token Then
                        ' Apply alternative color and font to highlight keyword.
                        code.SelectionColor = Color.Blue
                        code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
                        Exit For
                    End If
                Next

                For i As Integer = 0 To keywords2.Length - 1
                    If keywords2(i) = token Then
                        ' Apply alternative color and font to highlight keyword. 
                        code.SelectionColor = Color.DeepSkyBlue
                        code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
                        Exit For
                    End If
                Next

            End If
            code.SelectedText = token

        Next

        If ending = False Then
            code.SelectedText = vbLf
        End If

    End Sub

    Function StringParserArrDs(ByVal StringToParse As String, ByVal DelimeterChars() As String) As String()

        Dim arr(-1) As String

        Dim ins As Boolean = False
        Dim ch As String = ""
        Dim acc As String = ""
        Dim i As Integer = -1
        Dim len As Integer = StringToParse.Length - 1

        Do Until i = len
            i = i + 1

            ch = StringToParse.Chars(i)

            Dim ic As String = CStr(CChar(""""))

            If ch = ic Then
                If ins = False Then
                    ins = True
                ElseIf ins = True Then
                    ins = False
                End If
            End If

            Dim match As Boolean = False

            For Each s As String In DelimeterChars

                If ch = s Then
                    match = True
                End If

            Next

            If match = True Then
                If ins = False Then
                    If acc <> "" Then
                        ReDim Preserve arr(UBound(arr) + 1)
                        arr(UBound(arr)) = acc
                    End If
                    acc = ""
                ElseIf ins = True Then
                    acc = acc & ch
                End If
            Else
                acc = acc & ch
            End If

            If i = len Then
                If acc <> "" Then
                    ReDim Preserve arr(UBound(arr) + 1)
                    arr(UBound(arr)) = acc
                End If
                acc = ""
            End If

        Loop

        Return arr
    End Function

    Sub ParseLine()

        If high = False Then
            code.SelectionColor = Color.Black
        End If

        If doparse = True And high = True Then
            ' Calculate the starting position of the current line.
            Dim start As Integer = 0, [end] As Integer = 0
            For start = code.SelectionStart - 1 To 1 Step -1
                If code.Text(start) = ControlChars.Lf Then
                    start += 1
                    Exit For
                End If
            Next

            ' Calculate the end position of the current line.
            For [end] = code.SelectionStart To code.Text.Length - 1
                If code.Text([end]) = ControlChars.Lf Then
                    Exit For
                End If
            Next

            ' Extract the current line that is being edited.
            Dim line As String = ""
            If start = 0 Or start > 0 Then
                line = code.Text.Substring(start, [end] - start)
            End If
            ' Backup the users current selection point.
            Dim selectionStart As Integer = code.SelectionStart
            Dim selectionLength As Integer = code.SelectionLength

            ' Split the line into tokens.
            Dim r As New Regex("([ \t{}()<>:;$,])")
            Dim tokens As String() = r.Split(line)
            Dim index As Integer = start
            If index = 0 Or index > 0 Then

                Dim ins As Boolean = False

                For Each token As String In tokens

                    ' Set the token's default color and font.
                    code.SelectionStart = index
                    code.SelectionLength = token.Length
                    code.SelectionColor = Color.Black
                    code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Regular)

                    ' Check for a comment.
                    If token = "//" OrElse token.StartsWith("//") Then
                        ' Find the start of the comment and then extract the whole comment.
                        Dim length As Integer = line.Length - (index - start)
                        Dim commentText As String = code.Text.Substring(index, length)
                        code.SelectionStart = index
                        code.SelectionLength = length
                        code.SelectionColor = Color.Green
                        code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Regular)
                        Exit For
                    End If


                    If token Like """" & "*" Then
                        If ins = True Then
                            ins = False
                        Else
                            ins = True
                        End If
                        If token Like """" & "*" & """" Then
                            ins = False
                        End If
                        code.SelectionColor = Color.IndianRed
                        code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
                    ElseIf token Like "*" & """" Then
                        code.SelectionColor = Color.IndianRed
                        code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
                        ins = False
                    End If

                    If token Like "'*" Then
                        If ins = True Then
                            ins = False
                        Else
                            ins = True
                        End If
                        If token Like "'*'" Then
                            ins = False
                        End If
                        code.SelectionColor = Color.IndianRed
                        code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
                    ElseIf token Like "*'" Then
                        code.SelectionColor = Color.IndianRed
                        code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
                        ins = False
                    End If

                    If ins = True Then
                        code.SelectionColor = Color.IndianRed
                        code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
                    End If

                    If ins = False Then
                        ' Check whether the token is a keyword. 
                        For i As Integer = 0 To keywords.Length - 1
                            If keywords(i) = token Then
                                ' Apply alternative color and font to highlight keyword. 
                                code.SelectionColor = Color.Blue
                                code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
                                Exit For
                            End If
                        Next

                        For i As Integer = 0 To keywords2.Length - 1
                            If keywords2(i) = token Then
                                ' Apply alternative color and font to highlight keyword. 
                                code.SelectionColor = Color.DeepSkyBlue
                                code.SelectionFont = New Font("Lucida Console", 10, FontStyle.Bold)
                                Exit For
                            End If
                        Next

                    End If


                    index += token.Length
                Next
            End If
            ' Restore the users current selection point. 
            code.SelectionStart = selectionStart
            code.SelectionLength = selectionLength
        End If

    End Sub

    Private Sub code_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles code.TextChanged
        If code.Text <> "" Then

            ParseLine()

        End If
    End Sub


    Private Sub SaveToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SaveToolStripMenuItem.Click
        SaveCode()
    End Sub

    Private Sub OpenToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenToolStripMenuItem.Click
        OpenCode()
    End Sub

    Private Sub BuildToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BuildToolStripMenuItem.Click
        Compile()
    End Sub

    Private Sub RunToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RunToolStripMenuItem.Click
        Dim rtb As RichTextBox = New RichTextBox()

        rtb.LoadFile(address.Text, RichTextBoxStreamType.PlainText)
        Dim proglines As String() = rtb.Text.Split(New [Char]() {vbLf})

        Dim assem As String = ""
        Dim type As String = ""

        Dim s As String
        For Each s In proglines

            If s Like "assembly *" Then
                Dim r As LinqXmlData.FileUtils = New LinqXmlData.FileUtils()
                Dim split() As String = r.StringParser(s, " ")

                If split.Length = 2 Then
                    assem = split(1)
                    type = "exe"
                ElseIf split.Length = 3 Then
                    assem = split(1)
                    type = split(2)
                End If

                GoTo finito
            End If

        Next

finito:

        If type = "exe" Then

            Dim addr As String = address.Text
            Dim slashcount As Integer = 0
            Dim len As Integer = addr.Length - 1
            Dim i As Integer = -1

            Do Until i = len

                i = i + 1
                Dim ch As String = addr.Chars(i)
                If ch = "\" Then
                    slashcount = i
                End If

            Loop

            Dim d As String = ""
            i = -1

            Do Until i = slashcount
                i = i + 1
                d = d & addr.Chars(i)
            Loop

            Process.Start(d & "\" & assem & "." & type)
        Else
            MsgBox("The output is a class library which cannot be executed separately!!")
        End If
    End Sub

    Private Sub OnToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OnToolStripMenuItem.Click
        high = True
    End Sub

    Private Sub OffToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OffToolStripMenuItem.Click
        high = False
    End Sub

    Private Sub RefreshToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RefreshToolStripMenuItem.Click
        doparse = False

        If code.Text <> "" Then
            Dim split As String() = code.Text.Split(New [Char]() {vbLf})

            code.Clear()

            Dim len As Integer = split.Length - 1
            Dim i As Integer

            For i = 0 To len
                Dim s As String = split(i)
                If i = len Then
                    ParseAll(s, True)
                Else
                    ParseAll(s, False)
                End If

            Next

        End If
        doparse = True
    End Sub

    Private Sub VBEditorToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles VBEditorToolStripMenuItem.Click
        Form2.Show()
    End Sub

    Private Sub AboutToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AboutToolStripMenuItem.Click
        AboutBox1.Show()
    End Sub

    Private Sub ExitToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ExitToolStripMenuItem.Click
        Me.Close()
    End Sub

    Private Sub NETToolsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NETToolsToolStripMenuItem.Click
        Form3.Show()
    End Sub
End Class